// api/user_api/bind_account.go
package user_api

import (
	"github.com/gin-gonic/gin"
	"github.com/mojocn/base64Captcha"
	"muziai-server/global"
	"muziai-server/models"
	"muziai-server/models/ctype"
	"muziai-server/utils/jwts"
	"muziai-server/utils/res"
	"regexp"
)

type BindAccountRequest struct {
	Value     string               `json:"value" binding:"required"`
	BindType  ctype.RegisterSource `json:"bindType" binding:"required,oneof=1 2"`
	Captcha   string               `json:"captcha"`                           // 图形验证码
	CaptchaID string               `json:"captchaID"`                         // 图形验证码
	Step      int                  `json:"step" binding:"required,oneof=1 2"` // 步骤
	Code      string               `json:"code"`                              // 第二步进行校验的
}

var bindStore = base64Captcha.DefaultMemStore

func (u UserApi) BindAccountView(c *gin.Context) {
	var cr BindAccountRequest
	err := c.ShouldBindJSON(&cr)
	if err != nil {
		res.FailWithError(c, err)
		return
	}

	_claims, _ := c.Get("claims")
	claims := _claims.(*jwts.Claims)

	switch cr.BindType {
	case ctype.EmailRegister:
		result, _ := regexp.MatchString(`^([\w\.\_\-]{2,10})@(\w{1,}).([a-z]{2,4})$`, cr.Value)
		if !result {
			res.FailWithMsg(c, "邮箱格式错误")
			return
		}
		//case ctype.TelRegister:
		//	result, _ := regexp.MatchString(`^1[3-9]\d{9}$`, cr.Value)
		//	if !result {
		//		res.FailWithMsg(c, "手机号格式错误")
		//		return
		//	}
	}

	// 不同步骤的校验
	switch cr.Step {
	case 1:
		if cr.Captcha == "" || cr.CaptchaID == "" {
			res.FailWithMsg(c, "请输入图形验证码")
			return
		}

		ok := store.Verify(cr.CaptchaID, cr.Captcha, true)
		if !ok {
			res.FailWithMsg(c, "验证码校验失败")
			return
		}

		//查这个手机号，邮箱是否存在，不存在才去发短信
		userHas, msg := u.UserService.HasBindAccount(cr.BindType, cr.Value)
		if userHas {
			res.FailWithMsg(c, msg)
			return
		}
		code, msg := u.UserService.UserSendCode(cr.BindType, cr.Value, ctype.BindAccountTemplateID)
		bindStore.Set(cr.Value, code)
		res.OkWithMsg(c, msg)
		return
	case 2:
		if cr.Code == "" {
			res.FailWithMsg(c, "验证码不能为空")
			return
		}
		ok := bindStore.Verify(cr.Value, cr.Code, false)
		if !ok {
			res.FailWithMsg(c, "验证码验证失败")
			return
		}

		var user models.UserModel
		global.DB.Take(&user, claims.UserID)

		var maps = map[string]any{}
		switch cr.BindType {
		case ctype.EmailRegister:
			maps["email"] = cr.Value
		case ctype.TelRegister:
			maps["tel"] = cr.Value
		}

		global.DB.Model(&user).Updates(maps)

		res.OkWithMsg(c, "绑定成功")
	}
}
